﻿//using MediatR;
//using Microsoft.EntityFrameworkCore;
//using Microsoft.EntityFrameworkCore.Storage;
//using Microsoft.Extensions.Logging;
//using Sgr.Domain.Uow;
//using System;
//using System.Collections.Concurrent;
//using System.Collections.Generic;
//using System.Data;
//using System.Linq;
//using System.Text;
//using System.Threading;
//using System.Threading.Tasks;

//namespace Sgr.EntityFrameworkCore
//{
//    /// <summary>
//    /// 支持模块化的工作单元实现，包装DbContext
//    /// </summary>
//    public class EfCoreUnitOfWork<TModule, TDbContext> : IUnitOfWork<TModule>
//        where TDbContext : DbContext
//        where TModule : class
//    {
//        protected readonly IMediator _mediator;
//        protected readonly TDbContext _dbContext;
//        protected readonly ILogger<EfCoreUnitOfWork<TModule, TDbContext>> _logger;

//        protected IDbContextTransaction? _transaction;
//        protected ConcurrentBag<Func<Task>> _completedHandlers;
//        protected int _transactionCount;
//        protected bool _disposed;

//        public EfCoreUnitOfWork(
//            TDbContext dbContext,
//            IMediator mediator,
//            ILogger<EfCoreUnitOfWork<TModule, TDbContext>> logger)
//        {
//            _dbContext = dbContext ?? throw new ArgumentNullException(nameof(dbContext));
//            _mediator = mediator ?? throw new ArgumentNullException(nameof(mediator));
//            _logger = logger ?? throw new ArgumentNullException(nameof(logger));

//            _completedHandlers = new ConcurrentBag<Func<Task>>();
//            _transactionCount = 0;
//            _disposed = false;
//        }

//        /// <summary>
//        /// 获取包装的DbContext
//        /// </summary>
//        public TDbContext DbContext => _dbContext;

//        #region IUnitOfWork

//        /// <summary>
//        /// 工作单元名称
//        /// </summary>
//        public virtual string ModuleName => typeof(TModule).Name;

//        /// <summary>
//        /// 执行Save操作
//        /// </summary>
//        /// <param name="cancellationToken"></param>
//        /// <returns></returns>
//        public virtual async Task<bool> SaveEntitiesAsync(CancellationToken cancellationToken = default)
//        {
//            // Dispatch Domain Events collection.
//            // Choices:
//            // A) Right BEFORE committing data (EF SaveChanges) into the DB will make a single transaction including
//            // side effects from the domain event handlers which are using the same DbContext with "InstancePerLifetimeScope" or "scoped" lifetime
//            // B) Right AFTER committing data (EF SaveChanges) into the DB will make multiple transactions.
//            // You will need to handle eventual consistency and compensatory actions in case of failures in any of the Handlers.

//            // 选择 A) 在提交数据前执行领域事件
//            // - 优点：所有操作在同一个事务中
//            // - 适用于领域事件处理器使用相同 DbContext 的场景

//            // 选择 B) 在提交数据后执行领域事件
//            // - 会产生多个事务
//            // - 需要处理最终一致性
//            // - 需要处理补偿操作

//            ThrowIfDisposed();

//            await _mediator.DispatchDomainEventsAsync(_dbContext);

//            //this.ChangeTracker.DetectChanges();

//            // After executing this line all the changes (from the Command Handler and Domain Event Handlers)
//            // performed through the DbContext will be committed
//            _ = await _dbContext.SaveChangesAsync(cancellationToken);

//            return true;
//        }

//        #endregion IUnitOfWork

//        #region IUnitOfWorkTransactions

//        /// <summary>
//        /// 是否有活动的事务
//        /// </summary>
//        public virtual bool HasActiveTransaction => _transaction != null && _transactionCount > 0;

//        /// <summary>
//        /// 开始新事务
//        /// </summary>
//        /// <param name="isolationLevel">事务隔离级别</param>
//        /// <param name="cancellationToken">取消令牌</param>
//        /// <returns></returns>
//        public virtual async Task BeginTransactionAsync(
//            IsolationLevel isolationLevel = IsolationLevel.ReadCommitted,
//            CancellationToken cancellationToken = default)
//        {
//            ThrowIfDisposed();

//            // 如果已有事务，增加计数器（支持嵌套）
//            if (_transactionCount > 0)
//            {
//                _transactionCount++;
//                return;
//            }

//            // 如果没有活动事务，创建一个新事务
//            if (_transaction == null)
//            {
//                _transaction = await _dbContext.Database.BeginTransactionAsync(
//                    isolationLevel,
//                    cancellationToken); ;

//                _transactionCount = 1;
//            }
//        }

//        /// <summary>
//        /// 异步提交事务
//        /// </summary>
//        /// <param name="cancellationToken"></param>
//        /// <returns></returns>
//        public virtual async Task CommitAsync(CancellationToken cancellationToken = default)
//        {
//            ThrowIfDisposed();

//            try
//            {
//                // 减少事务计数
//                _transactionCount--;

//                // 只有当计数归零时才真正提交事务（最外层事务）
//                if (_transactionCount == 0 && _transaction != null)
//                {
//                    // 保存更改
//                    await SaveEntitiesAsync(cancellationToken);

//                    // 提交事务
//                    await _transaction.CommitAsync(cancellationToken);

//                    // 释放事务资源
//                    await CleanupTransactionAsync();

//                    // 执行完成事件处理程序
//                    await OnCompletedAsync();
//                }
//                // 对于嵌套事务，只保存更改，不提交事务
//                else if (_transactionCount > 0)
//                {
//                    await SaveEntitiesAsync(cancellationToken);
//                }
//            }
//            catch
//            {
//                // 出错时回滚事务
//                await RollbackAsync(cancellationToken);
//                throw;
//            }
//        }

//        /// <summary>
//        /// 异步回滚事务
//        /// </summary>
//        /// <param name="cancellationToken"></param>
//        /// <returns></returns>
//        public virtual async Task RollbackAsync(CancellationToken cancellationToken = default)
//        {
//            try
//            {
//                // 嵌套事务全部回滚
//                if (_transaction != null)
//                {
//                    await _transaction.RollbackAsync(cancellationToken);
//                }
//            }
//            finally
//            {
//                await CleanupTransactionAsync();
//            }
//        }

//        /// <summary>
//        /// 清理事务资源
//        /// </summary>
//        /// <returns></returns>
//        private async Task CleanupTransactionAsync()
//        {
//            if (_transaction != null)
//            {
//                await _transaction.DisposeAsync();
//                _transaction = null;
//            }

//            _transactionCount = 0;
//        }

//        #endregion IUnitOfWorkTransactions

//        #region IUnitOfWorkEventHandling

//        /// <summary>
//        /// 添加事务提交成功后的处理事件
//        /// </summary>
//        /// <param name="handler"></param>
//        public virtual void AddCompletedHandler(Func<Task> handler)
//        {
//            Check.NotNull(handler, nameof(handler));

//            ThrowIfDisposed();

//            _completedHandlers.Add(handler);
//        }

//        protected virtual async Task OnCompletedAsync()
//        {
//            var handlers = _completedHandlers.ToArray();

//            foreach (var handler in handlers)
//            {
//                try
//                {
//                    await handler.Invoke().ConfigureAwait(false);
//                }
//                catch (Exception ex)
//                {
//                    _logger.LogError(ex, "Error executing transaction completed handler for transaction {TransactionId}",
//                        _transaction?.TransactionId);
//                }
//            }
//        }

//        #endregion IUnitOfWorkEventHandling

//        #region IDisposable

//        protected virtual void Dispose(bool disposing)
//        {
//            if (!_disposed)
//            {
//                if (disposing)
//                {
//                    try
//                    {
//                        _transaction?.Dispose();
//                    }
//                    catch (Exception ex)
//                    {
//                        _logger.LogError(ex, "释放EfCoreUnitOfWork类中数据库事务资源时发生异常");
//                    }
//                    finally
//                    {
//                        _transaction = null;
//                        _transactionCount = 0;
//                    }

//                    _completedHandlers.Clear();

//                    // 注意：我们不应该在这里Dispose DbContext，
//                    // 因为它通常由DI容器管理生命周期
//                }

//                _disposed = true;
//            }
//        }

//        public void Dispose()
//        {
//            Dispose(true);
//            GC.SuppressFinalize(this);
//        }

//        public async ValueTask DisposeAsync()
//        {
//            if (!_disposed)
//            {
//                // 异步释放托管资源
//                if (_transaction != null)
//                {
//                    try
//                    {
//                        await _transaction.DisposeAsync().ConfigureAwait(false);
//                    }
//                    catch (Exception ex)
//                    {
//                        _logger.LogError(ex, "释放EfCoreUnitOfWork类中数据库事务资源时发生异常");
//                    }
//                    finally
//                    {
//                        _transaction = null;
//                        _transactionCount = 0;
//                    }
//                }

//                _completedHandlers.Clear();

//                _disposed = true;
//            }

//            // 抑制终结器
//            GC.SuppressFinalize(this);
//        }

//        protected void ThrowIfDisposed()
//        {
//            ObjectDisposedException.ThrowIf(_disposed, GetType().Name);
//        }

//        #endregion IDisposable
//    }
//}